/**
 * @file encoder.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-08-29
 *
 * @copyright Copyright (c) 2023
 *
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "bflb_gpio.h"
#include "touch.h"
#include "encoder.h"
#include "qyq_triled_drive.h"
#include "custom.h"
#include "log.h"
#include "lv_port_indev.h"
#include "gui_guider.h"
#include "homeAssistantPort.h"
#define DBG_TAG "ENCODER"

#define ENCODER_PUSH GPIO_PIN_24
#define ENCODER_B GPIO_PIN_28
#define ENCODER_A GPIO_PIN_26

#define WS2812DIN GPIO_PIN_10
#define WS2812NUM 65
#define MODE_DELAY_MS 40
static struct bflb_device_s* gpio;
static xTimerHandle ENCODER_1_timer;
static xTimerHandle ENCODER_2_timer;
static xTimerHandle ENCODER_3_timer;
xTaskHandle mode_task_handle;

xTaskHandle mode1_task_handle;
xTaskHandle mode2_task_handle;
xTaskHandle mode3_task_handle;
bool mode1_is_Suspend;
bool mode2_is_Suspend;
bool mode3_is_Suspend;

uint8_t red = 255;
uint8_t green = 0;
uint8_t blue = 0;
int32_t end = 0;

static bool encoder_diff_enable = true;

void* encoder_task;

lv_obj_t* get_current_layer_obj(void);
lv_group_t* get_encoder_group(void);
static void triled_drive_mode_task(void* arg);
/**
 * @brief encoder_timer_cb
 *   旋钮单独使用一个中断来识别会导致旋转方向识别不稳定，大概率出现误触，
 *   使用的定时器以1ms为单位计算另外一个输入的电平时间可以有效减小误触
 *   顺时针方向波形：
 * A:  _______      _______
 *            |____|       |_____
 * B:  __________      _______
 *               |____|       |____
 *
 * 逆时针方向波形：
 * A: ________      _______
 *            |____|       |_____
 * B:_______      ______
 *          |____|      |________
 *
 * @param xTimer
*/
static void encoder_timer_cb(TimerHandle_t xTimer)
{
    static int timer_cont;
    int timer_id = pvTimerGetTimerID(xTimer);

    switch (timer_id) {
        case 0: //顺时针方向定时器
            if (bflb_gpio_read(gpio, ENCODER_B)&&bflb_gpio_read(gpio, ENCODER_A)==0) timer_cont++; //当 A和B都满足顺时针状态时，开始增加计时
            else {
                xTimerStop(ENCODER_1_timer, portMAX_DELAY);
                // LOG_I("encoder B io Higt timer=%d ms", timer_cont);
                if (timer_cont>4)xTaskNotify(encoder_task, 1, eSetValueWithOverwrite); //当时B的高电平时间超过4ms,则方向为顺时针
                timer_cont = 0;
            }
            break;
        case 1: //逆时针方向定时器
            if (bflb_gpio_read(gpio, ENCODER_B)==0&&bflb_gpio_read(gpio, ENCODER_A)==0) timer_cont++; //当 A和B都满足逆时针状态时，开始增加计时
            else {
                xTimerStop(ENCODER_2_timer, portMAX_DELAY);
                // LOG_I("encoder B  io low timer=%d ms", timer_cont);
                if (timer_cont>4)xTaskNotify(encoder_task, 2, eSetValueWithOverwrite);//当时B的低电平时间超过4ms,则方向为顺时针
                timer_cont = 0;
            }
            break;
        case 2://按钮定时器
            if (bflb_gpio_read(gpio, ENCODER_PUSH)==0) {
                timer_cont++;
                if (timer_cont>100) { //大于1s 即为长按
                    timer_cont = 0;
                    xTimerStop(ENCODER_3_timer, portMAX_DELAY);
                    xTaskNotify(encoder_task, 4, eSetValueWithOverwrite);//发送任务通知
                }
            }
            else {
                if (timer_cont<= 100) {//否则识别为点击

                    xTimerStop(ENCODER_3_timer, portMAX_DELAY);
                    xTaskNotify(encoder_task, 3, eSetValueWithOverwrite);
                }
                timer_cont = 0;
            }

            break;
    }

}

static void gpio_isr(uint8_t pin)
{
    BaseType_t xHigherPriorityTaskWoken;

    xHigherPriorityTaskWoken = pdFALSE;
    if (pin == ENCODER_PUSH) {
        //延迟100ms 之后查看是否已经按下，消抖
        encoder_diff_enable = false;
        if (!bflb_gpio_read(gpio, pin)) {
            bflb_mtimer_delay_ms(20);
            if (!bflb_gpio_read(gpio, pin))
                xTimerStartFromISR(ENCODER_3_timer, &xHigherPriorityTaskWoken);
        }
    }

    if (pin == ENCODER_A) {
        if (encoder_diff_enable) {
            if (bflb_gpio_read(gpio, ENCODER_B))
                xTimerStartFromISR(ENCODER_1_timer, &xHigherPriorityTaskWoken);
            else xTimerStartFromISR(ENCODER_2_timer, &xHigherPriorityTaskWoken);
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        }
    }

}

void my_encoder_init(void)
{
    gpio = bflb_device_get_by_name("gpio");

    bflb_gpio_init(gpio, ENCODER_PUSH, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio, ENCODER_B, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio, ENCODER_A, GPIO_INPUT| GPIO_PULLUP);

    bflb_gpio_int_init(gpio, ENCODER_PUSH, 0);
    bflb_gpio_int_init(gpio, ENCODER_A, 0);

    bflb_gpio_irq_attach(ENCODER_PUSH, gpio_isr);
    bflb_gpio_irq_attach(ENCODER_A, gpio_isr);

    bflb_irq_enable(gpio->irq_num);
}

void encoder_RGB_add(void)
{
    if (green == 0 && blue < 255)
    {
        red -= 15;
        blue += 15;
    }
    if (red == 0 && green < 255)
    {
        blue -= 15;
        green += 15;
    }
    if (blue == 0 && red < 255)
    {
        green -= 15;
        red += 15;
    }
}

void encoder_RGB_sub(void)
{
    if (green == 0 && red < 255)
    {
        red += 15;
        blue -= 15;
    }
    if (blue == 0 && green < 255)
    {
        red -= 15;
        green += 15;
    }
    if (red == 0 && blue < 255)
    {
        green -= 15;
        blue += 15;
    }
}
// extern void encoder_handler(uint8_t press_type);
static int element_id;
static int mode_element_id;
uint8_t element_id_old = 0;
uint8_t mode_element_id_old = 0;

static void screen_crtl_handler(lv_ui* ui, uint8_t press_mode, uint8_t screen_numble)
{
    switch (screen_numble)
    {
        //首页
        case 0:
        {

            if (press_mode==1)
                element_id++;
            else if (press_mode==2)
                element_id--;


            if (element_id>2) {
                element_id = 2;
            }
            if (element_id<0)
            {
                element_id = 0;
            }
            if (element_id<=2&&element_id>=0&&element_id_old!=element_id)
            {
                // element_id = 2;
                lv_obj_set_element_id(ui->main_carousel_1, element_id, LV_ANIM_ON);
                element_id_old = element_id;
            }
            //按钮点击
            if (press_mode==3)
            {
                switch (element_id_old)
                {
                    case 0:
                        lv_event_send(ui->main_cont_1, LV_EVENT_CLICKED, ui);
                        break;
                    case 1:
                        lv_event_send(ui->main_cont_2, LV_EVENT_CLICKED, ui);
                        break;
                    case 2:
                        lv_event_send(ui->main_cont_3, LV_EVENT_CLICKED, ui);
                        break;
                    default:
                        break;
                }
            }
        }
        break;
        //第一页 颜色设置叶
        case 1:
        {
            if (press_mode==1)
                encoder_RGB_add();
            else if (press_mode==2)
                encoder_RGB_sub();
            else if (press_mode==4) {
                lv_event_send(ui->RGB, LV_EVENT_LONG_PRESSED, ui);
                qyq_triled_drive_set_allcolor(0, 0, 0);
                qyq_triled_drive_turn_offall();
            }
            lv_color_hsv_t c_hsv = lv_color_rgb_to_hsv(red, green, blue);
            c_hsv.v = 30;
            lv_colorwheel_set_hsv(ui->RGB_cpicker_1, c_hsv);
            lv_color_t c = lv_color_hsv_to_rgb(c_hsv.h, c_hsv.s, c_hsv.v);
            qyq_triled_drive_set_allcolor(LV_COLOR_GET_R(c), LV_COLOR_GET_G(c), LV_COLOR_GET_B(c));

            ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
            sw_all->light_state = 1;
            homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_LIGHT, sw_all, sw_all->light_state);
        }
        break;
        case 2:
        {
            lv_color_hsv_t c_hsv = lv_color_rgb_to_hsv(red, green, blue);
            c_hsv.v = 30;
            lv_color_t c = lv_color_hsv_to_rgb(c_hsv.h, c_hsv.s, c_hsv.v);

            if (press_mode==1) {
                // encoder_RGB_add();
                end--;
                if (end<=0)end = 0;
                qyq_triled_drive_set_color(end, 0, 0, 0);
                ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
                sw_all->light_state = 1;
                homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_LIGHT, sw_all, sw_all->light_state);
            }
            else if (press_mode==2) {
                //  encoder_RGB_sub();
                ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
                sw_all->light_state = 1;
                homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_LIGHT, sw_all, sw_all->light_state);
                qyq_triled_drive_set_othercolor(end);
                qyq_triled_drive_set_color(end, LV_COLOR_GET_R(c), LV_COLOR_GET_G(c), LV_COLOR_GET_B(c));
                end++;
                if (end>64)end = 64;
            }

            else if (press_mode==4) {
                lv_event_send(ui->Quantity, LV_EVENT_LONG_PRESSED, ui);
                qyq_triled_drive_set_allcolor(0, 0, 0);
                qyq_triled_drive_turn_offall();
                end = 0;
            }
        }
        break;

        //模式设置
        case 3:
        {
            if (press_mode==1)
                mode_element_id++;
            else if (press_mode==2)
                mode_element_id--;

            if (mode_element_id>2) {
                mode_element_id = 2;
            }
            if (mode_element_id<0)
            {
                mode_element_id = 0;
            }

            if (mode_element_id<=2&&mode_element_id>=0&&mode_element_id!=mode_element_id_old)
            {
                // element_id = 2;
                lv_obj_set_element_id(ui->mode_carousel_1, mode_element_id, LV_ANIM_ON);
                mode_element_id_old = mode_element_id;
            }
            //按钮点击
            if (press_mode==3)
            {
                switch (mode_element_id_old)
                {
                    case 0:
                        lv_event_send(ui->mode_carousel_1_mode1, LV_EVENT_CLICKED, ui);
                        break;
                    case 1:
                        lv_event_send(ui->mode_carousel_1_mode2, LV_EVENT_CLICKED, ui);
                        break;
                    case 2:
                        lv_event_send(ui->mode_carousel_1_mode3, LV_EVENT_CLICKED, ui);
                        break;
                    default:
                        break;
                }
            }
            //长按
            if (press_mode==4) {
                lv_event_send(ui->mode, LV_EVENT_LONG_PRESSED, ui);
                qyq_triled_drive_turn_offall();

                if (mode1_task_handle!=NULL)
                    vTaskDelete(mode1_task_handle);
                if (mode2_task_handle!=NULL)
                    vTaskDelete(mode2_task_handle);
                if (mode3_task_handle!=NULL)
                    vTaskDelete(mode3_task_handle);

                vTaskDelete(mode_task_handle);
            }
        }
        break;
        default:
            break;
    }
}

void encoder_process_task(void* param)
{

    uint8_t press_mode = 0;
    lv_ui* ui = (lv_ui*)param;
    //创建定时器
    ENCODER_1_timer = xTimerCreate("encoder_b_timer", pdMS_TO_TICKS(1), pdTRUE, 0, encoder_timer_cb);//顺时针识别滤波定时器
    ENCODER_2_timer = xTimerCreate("encoder_BL_timer", pdMS_TO_TICKS(1), pdTRUE, 1, encoder_timer_cb);//逆时针识别滤波定时器
    ENCODER_3_timer = xTimerCreate("encoder_push_timer", pdMS_TO_TICKS(10), pdTRUE, 2, encoder_timer_cb);//长按识别
    static qyq_triled_control_block_t triled_list[64];
    qyq_triled_drive_init(triled_list, 64);

    qyq_triled_drive_turn_onall();
    while (1) {
        xTaskNotifyWait(0xffffffff, 0x00, &press_mode, portMAX_DELAY);
        bflb_irq_disable(gpio->irq_num);
        LOG_F("encode read=%d", press_mode);
        vTaskDelay(50/portTICK_PERIOD_MS);
        bflb_irq_enable(gpio->irq_num);
        // encoder_handler(press_mode);
        switch (press_mode) {
            case 1:
            {
                // encoder_handler(press_mode);
                screen_crtl_handler(ui, press_mode, ui->screen);
                LOG_D("press_mode==1");
            }
            break;
            case 2:
                screen_crtl_handler(ui, press_mode, ui->screen);

                LOG_D("press_mode==2");
                break;
            case 3:
                screen_crtl_handler(ui, press_mode, ui->screen);

                LOG_D("press_mode==3");
                encoder_diff_enable = true;
                break;
            case 4:
                screen_crtl_handler(ui, press_mode, ui->screen);
                encoder_diff_enable = true;
                LOG_D("press_mode==4");
                break;

            default:
                break;
        }
    }
}

static void triled_drive_set_led(uint8_t* triled_drive, uint8_t char_nunmble, lv_color_t _c)
{
    uint8_t led_id = 0x80;
    for (size_t i = 0;i<8;i++)
    {
        if ((led_id&char_nunmble))
            qyq_triled_drive_set_color(triled_drive[i], LV_COLOR_GET_R(_c), LV_COLOR_GET_G(_c), LV_COLOR_GET_B(_c));
        else
            qyq_triled_drive_set_color(triled_drive[i], 0, 0, 0);

        led_id >>= 1;
    }
}
static lv_color_t c[8];
static lv_color_hsv_t c_hsv[8];

/**
 * @brief 模式1
 *
 * @param arg
*/
static void mode1_task(void* arg)
{
    int j = 0;
    uint8_t mode1_leds[][8] = {
    {56,57,58,59,60,61,62,63},
    {55,54,53,52,51,50,49,48},
    {40,41,42,43,44,45,46,47},
    {39,38,37,36,35,34,33,32},
    {24,25,26,27,28,29,30,31},
    {23,22,21,20,19,18,17,16},
    {8,9,10,11,12,13,14,15},
    {7,6,5,4,3,2,1,0},
    };

    {
        qyq_triled_drive_set_allcolor(0, 0, 0);
        c_hsv[j] = lv_color_rgb_to_hsv(0, 176, 80);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 255);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 0);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(255, 85, 0);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(0, 255, 255);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(0, 0, 255);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(255, 255, 0);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

        c_hsv[j] = lv_color_rgb_to_hsv(0, 255, 0);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;
        c_hsv[j] = lv_color_rgb_to_hsv(0, 176, 80);
        c_hsv[j].v = 30;
        c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
        j++;

    }

    //点亮跑马灯珠

    for (size_t i = 0; i < 3; i++)
    {
        qyq_triled_drive_set_color(63-i, LV_COLOR_GET_R(c[0]), LV_COLOR_GET_G(c[0]), LV_COLOR_GET_B(c[0]));
    }
    int cnt_handle = 60;
    int cnt_w = 63;
    j = 0;
    ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
    sw_all->light_state = 1;
    homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_LIGHT, sw_all, sw_all->light_state);
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS));
        //点亮头部
        qyq_triled_drive_set_color(cnt_handle, LV_COLOR_GET_R(c[j]), LV_COLOR_GET_G(c[j]), LV_COLOR_GET_B(c[j]));
        //关闭尾部
        qyq_triled_drive_set_color(cnt_w, 0, 0, 0);

        cnt_handle--;
        cnt_w--;
        if (((cnt_handle+1)%8)==0)j++;
        if (cnt_handle<0) {
            cnt_handle = 63;
            j = 0;
        }
        if (cnt_w<0)cnt_w = 63;
    }
}
//模式2
static void mode2_task(void* arg)
{
    uint8_t square_1[] = { 27,28,35,36 };
    uint8_t square_2[] = { 18,19,20,21,26,29,34,37,42,43,44,45 };
    uint8_t square_3[] = { 9,10,11,12,13,14,17,22,25,30,33,38,41,46,49,50,51,52,53,54 };
    uint8_t square_4[] = { 0,1,2,3,4,5,6,7,8,15,16,23,24,31,32,39,40,47,48,55,56,57,58,59,60,61,62,63 };
    uint8_t j = 0;
    c_hsv[j] = lv_color_rgb_to_hsv(0, 176, 80);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 255);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 0);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(0, 0, 255);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j = 0;
    while (1)
    {
        triled_drive_set_color_arry(square_1, sizeof(square_1), LV_COLOR_GET_R(c[j]), LV_COLOR_GET_G(c[j]), LV_COLOR_GET_B(c[j]));
        j++;
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_2, sizeof(square_2), LV_COLOR_GET_R(c[j]), LV_COLOR_GET_G(c[j]), LV_COLOR_GET_B(c[j]));
        j++;
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_3, sizeof(square_3), LV_COLOR_GET_R(c[j]), LV_COLOR_GET_G(c[j]), LV_COLOR_GET_B(c[j]));
        j++;
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_4, sizeof(square_4), LV_COLOR_GET_R(c[j]), LV_COLOR_GET_G(c[j]), LV_COLOR_GET_B(c[j]));
        j = 0;
        // qyq_triled_drive_set_allcolor(0, 0, 0);
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        //收缩
        triled_drive_set_color_arry(square_4, sizeof(square_4), 0, 0, 0);
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_3, sizeof(square_3), 0, 0, 0);
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_2, sizeof(square_2), 0, 0, 0);
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry(square_1, sizeof(square_1), 0, 0, 0);
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
    }
}

static void mode3_task(void* arg)
{
    uint8_t j = 0;
    c_hsv[j] = lv_color_rgb_to_hsv(0, 0, 255);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(0, 255, 0);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 0);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;

    c_hsv[j] = lv_color_rgb_to_hsv(255, 255, 0);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j++;
    c_hsv[j] = lv_color_rgb_to_hsv(255, 0, 255);
    c_hsv[j].v = 30;
    c[j] = lv_color_hsv_to_rgb(c_hsv[j].h, c_hsv[j].s, c_hsv[j].v);
    j = 0;

    //第一步
    uint8_t square_2_1[] = { 35,29,30,31,33,34, 0,15,16,17 };
    uint8_t square_3_1[] = { 36,43,44,20,51,52,60,61,62,63 };
    uint8_t square_4_1[] = { 27,25,26,37,38,39,40,41,55,56 };
    uint8_t square_5_1[] = { 28,4, 5, 6, 7, 10,11,12,19,20 };
    //第二步
    uint8_t square_2_2[] = { 35,34,33,32,31,30,16 };
    uint8_t square_3_2[] = { 36,43,51,52,59,60,61 };
    uint8_t square_4_2[] = { 27,26,25,24,38,39,40 };
    uint8_t square_5_2[] = { 28,19,12,11,3,4,5, };
    //第三步
    uint8_t square_2_3[] = { 35,44,45,49,50,51,61,62,63 };
    uint8_t square_3_3[] = { 36,37,38,40,41,42,55,54,56 };
    uint8_t square_4_3[] = { 27,20,11,21,10,5,6,7,9 };
    uint8_t square_5_3[] = { 28,29,0,14,15,16,17,18,30 };
    //第四步
    uint8_t square_2_4[] = { 36,43,51,52,59,60,61 };
    uint8_t square_3_4[] = { 27,26,25,24,38,39,40 };
    uint8_t square_4_4[] = { 28,19,12,11,3,4,5 };
    uint8_t square_5_4[] = { 35,34,33,30,32,31,16 };
    //第五步
    uint8_t square_2_5[] = { 36,37,38,40,41,42,54,55,56 };
    uint8_t square_3_5[] = { 27,20,21,11,10,9,5,6,7 };
    uint8_t square_4_5[] = { 28,29,30,16,17,18,0,14,15 };
    uint8_t square_5_5[] = { 35,44,45,51,50,49,61,62,63 };
    //第六步
    uint8_t square_2_6[] = { 27,26,25,37,38,39,40,41,55 };
    uint8_t square_3_6[] = { 28,19,20,4,5,6,10,11,12 };
    uint8_t square_4_6[] = { 35,34,33,29,30,31,16,17,15 };
    uint8_t square_5_6[] = { 36,41,43,50,51,52,60,61,62 };
    //第七步
    uint8_t square_2_7[] = { 27,26,25,24,22,23,39 };
    uint8_t square_3_7[] = { 28,19,12,13,2,3,4 };
    uint8_t square_4_7[] = { 35,34,33,32,31,46,47 };
    uint8_t square_5_7[] = { 36,43,52,53,58,59,60 };

    //第八步
    uint8_t square_2_8[] = { 27,20,21,5,6,7,9,10,11 };
    uint8_t square_3_8[] = { 28,29,30,0,14,15,16,17,18 };
    uint8_t square_4_8[] = { 35,44,45,49,50,51,61,62,63 };
    uint8_t square_5_8[] = { 36,37,38,40,41,42,54,55,56 };
    uint8_t color_sun[] = { 0,1,2,3 };
    uint8_t color_sun_handle = 0;

    while (1)
    {
        ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
        triled_drive_set_color_arry_no_start(square_2_1, sizeof(square_2_1), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_1, sizeof(square_3_1), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_1, sizeof(square_4_1), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_1, sizeof(square_5_1), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry_no_start(square_2_1, sizeof(square_2_1), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_1, sizeof(square_3_1), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_1, sizeof(square_4_1), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_1, sizeof(square_5_1), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_2, sizeof(square_2_2), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_2, sizeof(square_3_2), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_2, sizeof(square_4_2), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_2, sizeof(square_5_2), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));

        triled_drive_set_color_arry_no_start(square_2_2, sizeof(square_2_2), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_2, sizeof(square_3_2), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_2, sizeof(square_4_2), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_2, sizeof(square_5_2), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_3, sizeof(square_2_3), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_3, sizeof(square_3_3), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_3, sizeof(square_4_3), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_3, sizeof(square_5_3), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry_no_start(square_2_3, sizeof(square_2_3), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_3, sizeof(square_3_3), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_3, sizeof(square_4_3), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_3, sizeof(square_5_3), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_4, sizeof(square_2_4), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_4, sizeof(square_3_4), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_4, sizeof(square_4_4), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_4, sizeof(square_5_4), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));

        triled_drive_set_color_arry_no_start(square_2_4, sizeof(square_2_4), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_4, sizeof(square_3_4), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_4, sizeof(square_4_4), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_4, sizeof(square_5_4), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_5, sizeof(square_2_5), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_5, sizeof(square_3_5), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_5, sizeof(square_4_5), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_5, sizeof(square_5_5), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry_no_start(square_2_5, sizeof(square_2_5), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_5, sizeof(square_3_5), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_5, sizeof(square_4_5), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_5, sizeof(square_5_5), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_6, sizeof(square_2_6), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_6, sizeof(square_3_6), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_6, sizeof(square_4_6), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_6, sizeof(square_5_6), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        triled_drive_set_color_arry_no_start(square_2_6, sizeof(square_2_6), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_6, sizeof(square_3_6), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_6, sizeof(square_4_6), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_6, sizeof(square_5_6), 0, 0, 0);
        // triled_drive_set_color_start();
        triled_drive_set_color_arry_no_start(square_2_7, sizeof(square_2_7), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_7, sizeof(square_3_7), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_7, sizeof(square_4_7), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_7, sizeof(square_5_7), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }
        vTaskDelay(pdMS_TO_TICKS(MODE_DELAY_MS+20));
        //步骤换颜色
        triled_drive_set_color_arry_no_start(square_2_7, sizeof(square_2_7), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_7, sizeof(square_3_7), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_7, sizeof(square_4_7), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_7, sizeof(square_5_7), 0, 0, 0);

        triled_drive_set_color_arry_no_start(square_2_8, sizeof(square_2_8), LV_COLOR_GET_R(c[color_sun[0]]), LV_COLOR_GET_G(c[color_sun[0]]), LV_COLOR_GET_B(c[color_sun[0]]));
        triled_drive_set_color_arry_no_start(square_3_8, sizeof(square_3_8), LV_COLOR_GET_R(c[color_sun[1]]), LV_COLOR_GET_G(c[color_sun[1]]), LV_COLOR_GET_B(c[color_sun[1]]));
        triled_drive_set_color_arry_no_start(square_4_8, sizeof(square_4_8), LV_COLOR_GET_R(c[color_sun[2]]), LV_COLOR_GET_G(c[color_sun[2]]), LV_COLOR_GET_B(c[color_sun[2]]));
        triled_drive_set_color_arry_no_start(square_5_8, sizeof(square_5_8), LV_COLOR_GET_R(c[color_sun[3]]), LV_COLOR_GET_G(c[color_sun[3]]), LV_COLOR_GET_B(c[color_sun[3]]));
        if (sw_all->light_state)
            triled_drive_set_color_start();
        else {
            qyq_triled_drive_turn_offall();
        }

        triled_drive_set_color_arry_no_start(square_2_8, sizeof(square_2_8), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_3_8, sizeof(square_3_8), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_4_8, sizeof(square_4_8), 0, 0, 0);
        triled_drive_set_color_arry_no_start(square_5_8, sizeof(square_5_8), 0, 0, 0);
        // triled_drive_set_color_start();
        //换位操作
        color_sun_handle = color_sun[0];
        for (size_t i = 0; i < 4; i++)
        {

            color_sun[i] = color_sun[i+1];
            if (i==3)color_sun[i] = color_sun_handle;
        }
    }
}
static void triled_drive_mode_task(void* arg)
{
    uint8_t mode = 0;
    qyq_triled_drive_set_allcolor(0, 0, 0);
    xTaskCreate(mode1_task, "mode1_task", 1024, NULL, 16, &mode1_task_handle);
    xTaskCreate(mode2_task, "mode2_task", 1024, NULL, 16, &mode2_task_handle);
    xTaskCreate(mode3_task, "mode3_task", 1024, NULL, 16, &mode3_task_handle);
    vTaskSuspend(mode1_task_handle);
    vTaskSuspend(mode2_task_handle);
    vTaskSuspend(mode3_task_handle);
    mode1_is_Suspend = true;
    mode2_is_Suspend = true;
    mode3_is_Suspend = true;
    while (1)
    {
        xTaskNotifyWait(0xffffffff, 0x00, &mode, portMAX_DELAY);
        ha_lh_entity_t* sw_all = homeAssistant_fine_entity(CONFIG_HA_ENTITY_LIGHT, "triled-all_01");
        sw_all->light_state = 1;
        homeAssistant_device_send_entity_state(CONFIG_HA_ENTITY_LIGHT, sw_all, sw_all->light_state);
        switch (mode) {
            case 0:
            {
                LOG_I("MODE= %d", mode);
                if (!mode2_is_Suspend) {
                    vTaskSuspend(mode2_task_handle);
                    // vTaskDelay(mode2_task_handle);
                    mode2_is_Suspend = true;
                }
                if (!mode3_is_Suspend) {
                    vTaskSuspend(mode3_task_handle);
                    // vTaskDelay(mode3_task_handle);
                    mode3_is_Suspend = true;
                }
                qyq_triled_drive_set_allcolor(0, 0, 0);
                vTaskResume(mode1_task_handle);

                mode1_is_Suspend = false;
            }
            break;
            case 1:
            {
                LOG_I("MODE= %d", mode);
                if (!mode1_is_Suspend)
                {
                    vTaskSuspend(mode1_task_handle);
                    // vTaskDelay(mode1_task_handle);
                    mode1_is_Suspend = true;
                }
                if (!mode3_is_Suspend) {
                    vTaskSuspend(mode3_task_handle);
                    // vTaskDelay(mode3_task_handle);
                    mode3_is_Suspend = true;
                }
                qyq_triled_drive_set_allcolor(0, 0, 0);
                vTaskResume(mode2_task_handle);

                mode2_is_Suspend = false;
            }
            break;
            case 2:
            {
                LOG_I("MODE= %d", mode);
                if (!mode1_is_Suspend) {
                    vTaskSuspend(mode1_task_handle);
                    // vTaskDelay(mode1_task_handle);
                    mode1_is_Suspend = true;
                }

                if (!mode2_is_Suspend) {
                    vTaskSuspend(mode2_task_handle);
                    // vTaskDelay(mode2_task_handle);
                    mode2_is_Suspend = true;
                }

                qyq_triled_drive_set_allcolor(0, 0, 0);
                vTaskResume(mode3_task_handle);

                mode3_is_Suspend = false;
            }
            break;
            default:
                break;
        }
    }

}

void Create_triled_drive_set_mode_task(void)
{
    xTaskCreate(triled_drive_mode_task, "mode_task", 1024*2, NULL, 16, &mode_task_handle);
}

int8_t triled_drive_set_mode(uint8_t mode)
{
    xTaskNotify(mode_task_handle, mode, eSetValueWithOverwrite);
    return 0;
}
